package CRESTAURANT;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer; 

/**
 * Some helper methods to get data and format it.
 */
public class Utilities {

    /**
     * Constant to indicate the <code>trim</code> method that
     * text has to be aligned right.
     */
    public static int RIGHT = 0;

    /**
     * Constant to indicate the <code>trim</code> method that
     * text has to be aligned left.
     */
    public static int LEFT = 1;

    /**
     * Adds blanks before or after the <code>text</code> passed as parameter
     * until the text has the width specified by the <code>size</code> param.
     * @param text Text to format
     * @param size Final number of chars in the string 
     * @param position Place where to add the characters
     * @return The text passed as parameter filled with spaces, before or after
     *    according to <code>position</code> and with the width indicated by 
     *    <code>size</code>
     */
    public static String trim(String text, int size, int position) {

        StringBuffer sb = new StringBuffer();
        String aux = "";
        int whitespaces;

        if (text != null) {
            aux = text;
        }

        whitespaces = size - aux.length();

        if (whitespaces > 0) {
            if (position == LEFT)
                sb.append(aux);
            for (int i=0;i<whitespaces;i++) {
                sb.append(" ");
            }
            if (position == RIGHT)
                sb.append(aux);
        } else {
            sb.append(aux.substring(0, size));
        }

        return sb.toString();
    }

    /**
     * Adds blanks before or after the <code>number</code> passed as parameter
     * until the text has the width specified by the <code>size</code> param.
     * @param number Number to format
     * @param size Final number of chars in the string 
     * @param position Place where to add the characters
     * @return The text passed as parameter filled with spaces, before or after
     *    according to <code>position</code> and with the width indicated by 
     *    <code>size</code>
     */
   public static String trim(int number, int size, int position) {
        String aux = Integer.toString(number);
        return trim(aux, size, position);
    }

    /**
     * Capitalizes the first letter of the string
     * @param s String to capitalize
     * @return String with the first letter capitalized
     */
    public static String capitalize(String s) {
        if (s == null || s.length() == 0) {
            return "";
        }

        char chars[] = s.toCharArray();
        chars[0] = Character.toUpperCase(chars[0]);
        return new String(chars);
    }

    /**
     * Allows to query the user through the screen and returns a string
     * with the user input.
     * A set of accepted values can be defined. Use null if no restriction
     * has to be applied.
     * 
	 * @param message Message to show to the user
     * @param possibleValues Accepted values.
     * @return User input
     */
    public static String getString(String message, String[] possibleValues) {
        String ret = null;
        boolean ok = false;

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        try {
            do {
                printMessage(message, possibleValues);
                ret = in.readLine();
                if (possibleValues != null) {
                    if (isValueInArray(possibleValues, ret)) {
                        ok = true;
                    } else {
                        System.out.println("Not a valid value");
                    }
                } else {
                    ok = true;
                }
            } while (!ok);
        } catch (IOException ex) {
            System.out.println("Error processing the data introduced");
        }
        return ret;
    }

	/**
     * Allows to query the user through the screen and returns an int
     * with the user input.
	 * @param message Message to show to the user
	 * @return User input
	 */
 	public static Integer getInteger( String message ) {
		Integer ret = null;
		String aux = null;
		boolean ok = false;

		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		do {
			printMessage( message );
			try {
				aux = in.readLine();
				ret = new Integer( aux );
				ok = true;
			} catch ( IOException ex ) {
			    ok = true;
				System.out.println( "Error processing the data introduced" );
			} catch ( NumberFormatException ex ) {
				System.out.println( "Incorrect number" );
			}
		}
		while ( !ok );

		return ret;
	}

    /**
     * Shows a message to the user, showing possible values in brackets.
     *
     * @param message Message to show to the user.
     * @param possibleValues List of allowed values.
     */
    private static void printMessage(String message, String[] possibleValues) {
        String values = "";

        if ((possibleValues != null) && (possibleValues.length > 0)) {
            StringBuffer sb = new StringBuffer();
            sb.append("(");
            for (int i = 0; i < possibleValues.length - 1; i++) {
                sb.append(possibleValues[i]).append("/");
            }
            sb.append(possibleValues[possibleValues.length - 1]);
            sb.append(")");
            values = sb.toString();
        }
        System.out.print(message + values + ": ");
    }

    /**
     * Shows a message to the user
     *
     * @param message Message to show
     */
    private static void printMessage(String message) {
        printMessage(message, (String[]) null);
    }

    /**
     * Returns true if the passed value is present in the passed array,
     * ignoring upper case.
     *
     * @param array Array where to look for the value
     * @param value Value to look in the array
     * @return True if the value is in the array.
     */
    public static boolean isValueInArray(String[] array, String value) {
        boolean ret = false;

        for (int i = 0; i < array.length; i++) {
            if (array[i].equalsIgnoreCase(value)) {
                ret = true;
                break;
            }
        }
        return ret;
    }

    /**
     * Allows to query the user through the screen and returns a string
     * with the user input.
	 * @param message Message to show to the user
     * @return User input
     */
    public static String getString(String message) {
        return getString(message, null);
    }

    /**
     * Get data from a file, separated by <code>separator</code>.
     * @param file Name of the file with the data
     * @param separator Separator for the fields
     * @return List with the fields in the file line
     * @throws FileNotFoundException File could not be found
     * @throws IOException Excepcion reading the file
     */
    public static List<String> readFile(String file, String separator)
            throws FileNotFoundException, IOException {
        List<String> data = new ArrayList<String>();
        BufferedReader br = new BufferedReader (new FileReader (file));

        String line = br.readLine();
        while (line != null)
        {
            String token;
            StringTokenizer st = new StringTokenizer(line, separator);
            while (st.hasMoreTokens()) {
                token = st.nextToken();
                data.add(token);
            }
            line = br.readLine();
        }
        br.close();
        return data;
    }
}